package cn.sangyy.gift.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.sangyy.gift.auth.client.LoginUserClient;
import cn.sangyy.gift.common.util.AjaxResult;
import cn.sangyy.gift.common.util.PageList;
import cn.sangyy.gift.common.util.code.CodeEnum;
import cn.sangyy.gift.constant.MqConstant;
import cn.sangyy.gift.domain.Employee;
import cn.sangyy.gift.domain.LoginUser;
import cn.sangyy.gift.domain.Tenant;
import cn.sangyy.gift.dto.TenantRegisterDto;
import cn.sangyy.gift.exception.GiftAssert;
import cn.sangyy.gift.mapper.EmployeeMapper;
import cn.sangyy.gift.mapper.TenantMapper;
import cn.sangyy.gift.query.TenantQuery;
import cn.sangyy.gift.service.ITenantService;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.commons.lang.time.DateUtils;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author sangyy
 * @since 2023-06-20
 */
@Service
public class TenantServiceImpl extends ServiceImpl<TenantMapper, Tenant> implements ITenantService {

    @Autowired
    private TenantMapper tenantMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private LoginUserClient loginUserClient;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public PageList<Tenant> selectPageList(TenantQuery query) {
        Page<Tenant> page = new Page<>(query.getPage(),query.getRows());
        //自己写查询条件实现多表关联查询和高级查询和分页
        List<Tenant> rows = tenantMapper.selectPageList(page,query);
        return new PageList<Tenant>(page.getTotal(), rows);
    }

    @Override
    public Tenant getById(Long id) {
        return tenantMapper.getById(id);
    }

    @Transactional
    @Override
    public AjaxResult settlement(TenantRegisterDto tenantRegisterDto) {
        //1.参数校验
        validate(tenantRegisterDto);
        Employee admin = tenantRegisterDto.getAdmin();
        Tenant tenant = tenantRegisterDto.getTenant();
        Long mealId = tenantRegisterDto.getMealId();
        Long typeId = tenantRegisterDto.getTypeId();
        //5.先添加管理员信息，因为管理员有登录id，所以先添加登录信息获取登录id
        //远程调用授权中心获取登录id
        LoginUser loginUser = new LoginUser();
        BeanUtils.copyProperties(admin,loginUser);
        loginUser.setType(0);
        AjaxResult ajaxResult = loginUserClient.addOrUpdate(loginUser);
        Long loginId = Long.valueOf(ajaxResult.getResultObj().toString());
        if(StrUtil.isBlankIfStr(loginId)){
            return ajaxResult;
        }
        //6.保存各个数据
        saveData(typeId, admin, tenant, mealId, loginId);
        //7.百度的人工智能审查审核租户信息 rocketmq
        auditInfo(tenant,admin);
        //9. @TODO 发送激活信息到管理员邮件 rocketmq
        //10. @TODO 管理员激活店铺，可以正常登录使用
        return AjaxResult.me().setMessage("入驻成功");
    }

    private void auditInfo(Tenant tenant,Employee admin) {
        tenant.setAdmin(admin);
        rocketMQTemplate.asyncSend(MqConstant.TENANT_REGISTER_AUDIT_TOPIC, tenant, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.println("成功发送租户审核信息");
            }
            @Override
            public void onException(Throwable throwable) {
                System.out.println("发送租户审核信息失败！");
                throwable.printStackTrace();
            }
        });
    }

    private void saveData(Long typeId, Employee admin, Tenant tenant, Long mealId, Long loginId) {
        admin.setState(0);
        admin.setLoginId(loginId);
        admin.setInputTime(new Date());
        admin.setType(5);
        employeeMapper.insert(admin);
        //添加租户
        tenant.setAdminId(admin.getId());
        tenant.setState(0);
        tenant.setRegisterTime(new Date());
        tenant.setTypeId(typeId);
        tenantMapper.insert(tenant);
        admin.setTenantId(tenant.getId());
        employeeMapper.updateById(admin);
        //8.添加套餐和租户关联表
        HashMap<String,Object> params = new HashMap<>();
        params.put("tenantId", tenant.getId());
        params.put("mealId", mealId);
        params.put("expireDate", DateUtils.addYears(new Date(),1));
        tenantMapper.addTenantMeal(params);
    }

    private void validate(TenantRegisterDto tenantRegisterDto){
        Employee admin = tenantRegisterDto.getAdmin();
        Tenant tenant = tenantRegisterDto.getTenant();
        //2.两次密码确认
        GiftAssert.assertStrEquals(admin.getPassword(),admin.getConfirmPassword(), CodeEnum.TWO_PASSWORD_ERROR);
        //3.判断租户是否存在 存在不能再次入住
        List<Tenant> tenants = tenantMapper.selectList(new EntityWrapper<Tenant>().eq("company_name", tenant.getCompanyName()));
        GiftAssert.assertListIsNull(tenants,CodeEnum.TENANT_EXIST_ERROR);
        //4.判断租户管理员是否存在,存在则提示登录后添加租户
        List<Employee> employees = employeeMapper.selectList(new EntityWrapper<Employee>().eq("username", admin.getUsername()));
        GiftAssert.assertListIsNull(employees,CodeEnum.TENANT_EMPLOYEE_EXIST_ERROR);
    }
}
